vmx: Enable WBINVD intercepts to avoid real WBINVD for non-vtd guests.
authorKeir Fraser <keir@xensource.com>
Fri, 9 Nov 2007 12:59:58 +0000 (12:59 +0000)
committerKeir Fraser <keir@xensource.com>
Fri, 9 Nov 2007 12:59:58 +0000 (12:59 +0000)
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/hvm/vmx/vmcs.c
xen/arch/x86/hvm/vmx/vmx.c
xen/include/asm-x86/hvm/vmx/vmcs.h
xen/include/asm-x86/hvm/vmx/vmx.h

index 851814dbf59e6f66e0f3c483c7837ab4557cadb1..7c0d692b8ce733e20da1470a6468e17dd37e5192 100644 (file)
@@ -106,7 +106,8 @@ static void vmx_init_vmcs_config(void)
     if ( _vmx_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS )
     {
         min = 0;
-        opt = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES;
+        opt = (SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES |
+               SECONDARY_EXEC_WBINVD_EXITING);
         _vmx_secondary_exec_control = adjust_vmx_controls(
             min, opt, MSR_IA32_VMX_PROCBASED_CTLS2);
     }
index e4858d1755b71d5c54bbdf17baf2a4b6966eb4ea..b44cab7885c64365b575b9e5416de7368e9b16d0 100644 (file)
@@ -2909,11 +2909,21 @@ asmlinkage void vmx_vmexit_handler(struct cpu_user_regs *regs)
     }
 
     case EXIT_REASON_INVD:
+    case EXIT_REASON_WBINVD:
     {
-        inst_len = __get_instruction_length(); /* Safe: INVD */
+        inst_len = __get_instruction_length(); /* Safe: INVD, WBINVD */
         __update_guest_eip(inst_len);
         if ( !list_empty(&(domain_hvm_iommu(v->domain)->pdev_list)) )
+        {
             wbinvd();
+            /* Disable further WBINVD intercepts. */
+            if ( (exit_reason == EXIT_REASON_WBINVD) &&
+                 (vmx_cpu_based_exec_control &
+                  CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) )
+                __vmwrite(SECONDARY_VM_EXEC_CONTROL,
+                          vmx_secondary_exec_control &
+                          ~SECONDARY_EXEC_WBINVD_EXITING);
+        }
         break;
     }
 
index 86ad4edfef87daf237ee95d90dd2427c68cff3a3..132aa1d529240f81df727489bc775108ea08d60d 100644 (file)
@@ -131,6 +131,7 @@ extern u32 vmx_vmexit_control;
 extern u32 vmx_vmentry_control;
 
 #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001
+#define SECONDARY_EXEC_WBINVD_EXITING           0x00000040
 extern u32 vmx_secondary_exec_control;
 
 extern bool_t cpu_has_vmx_ins_outs_instr_info;
index 28edcfe088efcabdb9acc45f69c10ae513c4f343..be0a3fa620e563532a10d9739353a5a4ec181b91 100644 (file)
@@ -71,18 +71,15 @@ void vmx_vlapic_msr_changed(struct vcpu *v);
 #define EXIT_REASON_IO_INSTRUCTION      30
 #define EXIT_REASON_MSR_READ            31
 #define EXIT_REASON_MSR_WRITE           32
-
 #define EXIT_REASON_INVALID_GUEST_STATE 33
 #define EXIT_REASON_MSR_LOADING         34
-
 #define EXIT_REASON_MWAIT_INSTRUCTION   36
 #define EXIT_REASON_MONITOR_INSTRUCTION 39
 #define EXIT_REASON_PAUSE_INSTRUCTION   40
-
 #define EXIT_REASON_MACHINE_CHECK       41
-
 #define EXIT_REASON_TPR_BELOW_THRESHOLD 43
 #define EXIT_REASON_APIC_ACCESS         44
+#define EXIT_REASON_WBINVD              54
 
 /*
  * Interruption-information format